''' Address tests
'''
import scopt.test.common
from scopt.mpu.business.settings.handlers import address


class AddressCreate(scopt.test.common.ScoptTest):
    '''Address creation tests
    MPU should:

    1. test_address_create_unique
        allow to create address
    2. test_address_create_duplicate
        allow to create address with same name
    3. test_address_create_read
        create address and retrieve it with returned address entry id
    '''
    def test_address_create_unique(self):
        request = self.request(address.create)
        request = _setup_request(request)

        response = self.send_request(request)

        self.assertStatus(response, 'OK')

    def test_address_create_duplicate(self):
        request = self.request(address.create)
        request = _setup_request(request)

        response = self.send_request(request)

        self.assertStatus(response, 'OK')

        response = self.send_request(request)

        self.assertStatus(response, 'OK')

    def test_address_create_read(self):
        create_request = self.request(address.create)
        create_request = _setup_request(create_request)
        create_response = self.send_request(create_request)

        select_request = self.request(address.select)
        select_request['reqd'] = {'id': create_response['resd']['id']}
        select_response = self.send_request(select_request)

        create_reqd = create_request['reqd']
        select_resd = select_response['resd'][0]
        del select_resd['id']

        self.assertDictEqual(create_reqd, select_resd)


class AddressSelect(scopt.test.common.ScoptTest):
    ''' Address select tests
    MPU should:

    1. test_address_select_one
        select one address by uom_id
    2. test_address_select_all
        select all addresses by not providing id
    3. test_address_select_none
        select none address by providing id of non existent record
    '''
    def test_address_select_one(self):
        request = self.request(address.select)
        request['reqd'] = {'id': 1}

        response = self.send_request(request)
        data = response['resd']

        self.assertStatus(response, 'OK')
        self.assertEqual(len(data), 1)

    def test_address_select_all(self):
        # There are two address rows in demo db
        request = self.request(address.select)
        request['reqd'] = {}

        response = self.send_request(request)
        data = response['resd']

        self.assertStatus(response, 'OK')
        self.assertEqual(len(data), 2)

    def test_address_select_none(self):
        # row with id of 200 is not present in demo data
        request = self.request(address.select)
        request['reqd'] = {'id': 200}

        response = self.send_request(request)
        data = response['resd']

        self.assertStatus(response, 'OK')
        self.assertEqual(len(data), 0)


class AddressUpdate(scopt.test.common.ScoptTest):
    '''Address update tests
    MPU should:

    1. test_address_update
        allow update address to other unique name
    2. test_address_update_invalid_id
        disallow update address with invalid id
    3. test_address_update_missing_id
        disallow update address with id is missing
    4. test_address_update_duplicate_values
        disallow update address to values which is are unique
    5. test_address_update_read
        update and read address by its ID
    '''
    def test_address_update(self):
        request = self.request(address.update)
        # Record with id=1 exists in demo DB
        request = _setup_request(request)
        request['reqd'] = {'id': 1}

        response = self.send_request(request)

        self.assertStatus(response, 'OK')

    def test_address_update_invalid_id(self):
        # rows with id over 100 are not part of demo data
        request = self.request(address.update)
        request = _setup_request(request)
        request['reqd']['id'] = 100

        response = self.send_request(request, pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.record_no.is_invalid')

    def test_address_update_missing_id(self):
        request = self.request(address.update)
        request = _setup_request(request)

        response = self.send_request(request, pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.record_no.is_none')

    def test_address_update_duplicate_name(self):
        # row with id 1 is part of demo data
        create_request = self.request(address.create)
        create_request = _setup_request(create_request)
        self.send_request(create_request)

        update_request = self.request(address.update)
        update_request = _setup_request(update_request)
        update_request['reqd']['id'] = 1

        update_response = self.send_request(update_request)

        self.assertStatus(update_response, 'OK')

    def test_address_update_read(self):
        # row with id 1 is part of demo data
        update_request = self.request(address.update)
        update_request = _setup_request(update_request)
        update_request['reqd']['id'] = 1
        self.send_request(update_request)

        select_request = self.request(address.select)
        select_request['reqd'] = {'id': 1}
        select_response = self.send_request(select_request)

        update_reqd = update_request['reqd']
        select_resd = select_response['resd'][0]

        self.assertDictEqual(update_reqd, select_resd)


def _setup_request(request):
    request['reqd'] = {'address_line_1': 'LINE 1 of address',
                       'address_line_2': 'LINE 2 of address',
                       'address_line_3': 'LINE 3 of address',
                       'city': 'CITY of address',
                       'state': 'STATE of address',
                       'country': 'COUNTRY of address',
                       'zip': 'ZIP of address'}
    return request
